#include "TransformOperationWidget.h"

#include "Core/MainWindow.h"
#include "FeatureShape/HistoryManager.h"
#include "FeatureShape/FeatureShape.h"
#include "Render/QIVtkSelectionPipeline.h"
#include <TopoDS_Edge.hxx>
#include <TopoDS.hxx>

TransformOperationWidget::TransformOperationWidget(MainWindow* inMainWindow, ShapeOperation* inOperation, QWidget* parent)
	: QRSWidgetBase(inMainWindow, inOperation, parent)
	, ui(new Ui::TransformOperationWidgetClass())
{
	ui->setupUi(this);

	ui->moveDirWidget->installEventFilter(this);
	ui->rotateStartWidget->installEventFilter(this);
	ui->rotateDirWidget->installEventFilter(this);

	connect(ui->cancel, &QPushButton::clicked, this, &TransformOperationWidget::close);
	connect(ui->modify, &QPushButton::clicked, this, &TransformOperationWidget::onModify);
    connect(ui->confirm, &QPushButton::clicked, this, &TransformOperationWidget::onConfirm);

	connect(m_mainWindow, &MainWindow::OnSelectedSubShapes, this, &TransformOperationWidget::OnSelectedSubShapes);
	connect(m_mainWindow, &MainWindow::OnLeftButtonDown, this, &TransformOperationWidget::onLeftButtonDown);

	m_moveDir = new RWTripleFloatInput(ui->moveDirX, ui->moveDirY, ui->moveDirZ);
	m_RotatePnt = new RWTripleFloatInput(ui->rotateStartX, ui->rotateStartY, ui->rotateStartZ);
	m_rotateDir = new RWTripleFloatInput(ui->rotateDirX, ui->rotateDirY, ui->rotateDirZ);

	m_mainWindow->SetCanMultiSelect(false);
	m_mainWindow->SetSelectionMode(SM_Edge);
	ui->moveDirWidget->setStyleSheet("background-color:rgb(255,178,102)");
}

TransformOperationWidget::~TransformOperationWidget()
{
	delete ui;
    delete m_moveDir;
    delete m_rotateDir;
    delete m_RotatePnt;
}

void TransformOperationWidget::closeEvent(QCloseEvent* event)
{
	m_mainWindow->SubWidgetClose(bIsConfirmed);
}

bool TransformOperationWidget::eventFilter(QObject* obj, QEvent* event)
{
	QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
	if (event->type() == QEvent::MouseButtonPress && mouseEvent->button() == Qt::LeftButton)
	{
		if (obj == ui->moveDirWidget && focusIndex != 0)
		{
			ui->moveDirWidget->setStyleSheet("background-color:rgb(255,178,102)");
			ui->rotateStartWidget->setStyleSheet("background-color: #FFFFFF;");
			ui->rotateDirWidget->setStyleSheet("background-color: #FFFFFF;");

			focusIndex = 0;
			m_mainWindow->SetSelectionMode(SM_Edge);
		}
		if (obj == ui->rotateStartWidget && focusIndex != 1)
		{
			ui->rotateStartWidget->setStyleSheet("background-color:rgb(255,178,102)");
			ui->moveDirWidget->setStyleSheet("background-color: #FFFFFF;");
			ui->rotateDirWidget->setStyleSheet("background-color: #FFFFFF;");

			focusIndex = 1;
			m_mainWindow->SetSelectionMode(SM_Vertex);
		}
		if (obj == ui->rotateDirWidget && focusIndex != 2)
		{
			ui->rotateDirWidget->setStyleSheet("background-color:rgb(255,178,102)");
			ui->moveDirWidget->setStyleSheet("background-color: #FFFFFF;");
			ui->rotateStartWidget->setStyleSheet("background-color: #FFFFFF;");

			focusIndex = 2;
			m_mainWindow->SetSelectionMode(SM_Edge);
		}
	}

	return QObject::eventFilter(obj, event);
}

void TransformOperationWidget::onModify()
{
	// 判断selectActor Num
	if (!m_mainWindow->GetSelectedActors().size())
	{
		return;
	}

	bool bIsValid = false;
	// 创建变换------>注意这里是先平移再旋转
	gp_Trsf transform;

	// 判断平移是否有效
	if (!m_moveDir->IsNearlyZero())
	{
		bIsValid = true;

		// 计算平移向量
		gp_Vec translationVec(m_moveDir->GetValue() * ui->translateLen->value());
		transform.SetTranslation(translationVec);
	}
	// 判断旋转是否有效
	if (!IsNearlyZero(ui->angel->value()) && !m_rotateDir->IsNearlyZero())
	{
		// 计算旋转
		gp_Trsf rotation;
		gp_Dir rotationDir(m_rotateDir->GetValue());
		gp_Pnt rotationStart(m_RotatePnt->GetValue());
		gp_Ax1 rotationAxis(rotationStart, rotationDir);
		rotation.SetRotation(rotationAxis, ui->angel->value());
		if (bIsValid)
		{
			transform = rotation * transform;
		}
		else
		{
			transform = rotation;
			bIsValid = true;
		}
	}

	if (!bIsValid)
	{
		std::cout << "transform is invalid" << std::endl;
		return;
	}

	// 遍历selectActor
	std::vector<Handle(QIVtkSelectionPipeline)> actors = m_mainWindow->GetSelectedActors();
	std::vector<int> selectedActorIndex;
	for (Handle(QIVtkSelectionPipeline) actor : actors)
	{
		selectedActorIndex.push_back(GetIndexFromActor(m_mainWindow->GetCachedActors(), actor));
	}
	for (Handle(QIVtkSelectionPipeline) actor : actors)
	{
		Handle(QIVtkSelectionPipeline) newActor = m_mainWindow->TransformActor(actor, transform, true);
		newActor->m_featureShape.reset(new FeatureShapeMix(newActor->OccShape()));
		newActor->m_featureShape->_position = newActor->m_position;
	}

	ShapeOperation* op = new TransformOperation("变换运算", selectedActorIndex, transform);
	m_mainWindow->GetHistoryManager()->applyOperation(op);

	// Reset data
	ui->translateLen->setValue(1.f);
	ui->angel->setValue(0);
	m_moveDir->SetValue(gp_Pnt());
    m_rotateDir->SetValue(gp_Vec());
	m_RotatePnt->SetValue(gp_Pnt());

	bIsConfirmed = true;
}

void TransformOperationWidget::onConfirm()
{
	onModify();
	close();
}

void TransformOperationWidget::OnSelectedSubShapes(QIVtkSelectionPipeline* actor)
{
	if (!m_mainWindow->GetSelectedShapes().size())
	{
		return;
	}

	const TopoDS_Shape& selectedShape = m_mainWindow->GetSelectedShapes().back();
	// 选取的不是边
	if (selectedShape.ShapeType() != TopAbs_EDGE)
	{
		return;
	}

	TopoDS_Edge selectedEdge = TopoDS::Edge(selectedShape);
	gp_Dir edgeDirection = GetEdgeDirection(selectedEdge);

	// 选择平移方向
	if (focusIndex == 0)
	{
		m_moveDir->SetValue(edgeDirection);
	}
	// 选择方向
	else if (focusIndex == 2)
	{

		m_rotateDir->SetValue(edgeDirection);
	}
}

void TransformOperationWidget::onLeftButtonDown()
{
	bool bPickerSuccess = false;
	gp_Pnt PickPos = gp_Pnt();
	m_mainWindow->GetVertexPickerTargetPos(bPickerSuccess, PickPos);
	if (bPickerSuccess)
	{
		OnPickPosition(PickPos);
	}
}

void TransformOperationWidget::OnPickPosition(const gp_Pnt& position)
{
	m_RotatePnt->SetValue(position);
}
